import Taro from "@tarojs/taro";
import { Toast } from ".";

const devHost = "https://lishua.yfchangketong.com";
const host = "https://posp.yflishuapartner.com";

const codeMessage: Record<number, string> = {
  200: "服务器成功返回请求的数据。",
  201: "新建或修改数据成功。",
  202: "一个请求已经进入后台排队（异步任务）。",
  204: "删除数据成功。",
  400: "发出的请求有错误，服务器没有进行新建或修改数据的操作。",
  401: "用户没有权限（令牌、用户名、密码错误）。",
  403: "用户得到授权，但是访问是被禁止的。",
  404: "发出的请求针对的是不存在的记录，服务器没有进行操作。",
  406: "请求的格式不可得。",
  410: "请求的资源被永久删除，且不会再得到的。",
  422: "当创建一个对象时，发生一个验证错误。",
  500: "服务器发生错误，请检查服务器。",
  502: "网关错误。",
  503: "服务不可用，服务器暂时过载或维护。",
  504: "网关超时。"
};

export class NetworkError extends Error {
  public readonly code: number;
  constructor(message: string, code: number) {
    super(message);
    Object.setPrototypeOf(this, NetworkError.prototype);
    this.code = code;
  }
}

export async function post<T, P extends Record<string, any> = any>(
  api: string,
  params: P = {} as any,
  shouldRefreshCookie: boolean = false
) {
  let Cookie;
  try {
    Cookie = Taro.getStorageSync("Cookie");
  } catch {
    Cookie = undefined;
  }
  let resp: Taro.request.SuccessCallbackResult<NetworkResponse<T>>;
  try {
    resp = await Taro.request<NetworkResponse<T>, NetworkRequestParams<P>>({
      method: "POST",
      header: {
        "content-type": "application/json",
        Cookie
      },
      url: `${devHost}${api}`,
      data: {
        data: params
      },
      credentials: "include"
    });
    if (resp.statusCode !== 200) {
      const msg = codeMessage[resp.statusCode] ?? "网络请求失败";
      Toast(msg);
      throw Error(msg);
    }
    if ((!Cookie || shouldRefreshCookie) && resp.header["Set-Cookie"]) {
      Taro.setStorageSync("Cookie", resp.header["Set-Cookie"]);
    }
  } catch (err) {
    let msg = "网络异常";
    if (err instanceof Response && codeMessage[err.status])
      msg = codeMessage[err.status];
    else if (err instanceof Error && err.message) msg = err.message;
    Toast(msg);
    throw Error(msg);
  }
  const { data: res } = resp;
  if (res.code === 200 && res.enmsg === "ok") return res.data;
  else if (res.code === 401) {
    if (Cookie) Taro.removeStorageSync("Cookie");
    Taro.reLaunch({ url: "/subPackage/pages/auth/login/index" });
  }
  Toast(res.cnmsg);
  throw new NetworkError(res.cnmsg, res.code);
}
